package com.pb.wkflow.core.factor.behavior;

import com.pb.infra.oth.util.SpringContextUtil;
import lombok.extern.slf4j.Slf4j;
import org.camunda.bpm.engine.impl.bpmn.behavior.SequentialMultiInstanceActivityBehavior;
import org.camunda.bpm.engine.impl.pvm.PvmActivity;
import org.camunda.bpm.engine.impl.pvm.delegate.ActivityExecution;
import org.camunda.bpm.engine.impl.pvm.process.ActivityImpl;

import static com.pb.wkflow.core.config.Constants.NUMBER_OF_PASS_INSTANCES;

/**
 * 串行会签解析行为
 * @author 苗益辉
 * @date 2022/5/17 16:34
 */
@Slf4j
public class MySequentialMultiInstanceActivityBehavior extends SequentialMultiInstanceActivityBehavior {

    @Override
    public void execute(ActivityExecution execution) throws Exception {
        log.info("MySequentialMultiInstanceActivityBehavior executionId：{},activityId： {}",
                execution.getExecutions(), execution.getCurrentActivityId());
        DefaultMultiInstanceActivityBehavior behavior = SpringContextUtil.getBean(DefaultMultiInstanceActivityBehavior.class);
        behavior.defaultExecute(execution);
        super.execute(execution);
    }

    @Override
    protected void createInstances(ActivityExecution execution, int nrOfInstances) throws Exception {

        prepareScope(execution, nrOfInstances);
        setLoopVariable(execution, NUMBER_OF_ACTIVE_INSTANCES, 1);
        setLoopVariable(execution, NUMBER_OF_PASS_INSTANCES, 0);
        ActivityImpl innerActivity = getInnerActivity(execution.getActivity());
        performInstance(execution, innerActivity, 0);
    }

    /**
     *  表达式涉及 nrOfPassInstances 和 nrOfInstances
     * @param scopeExecution scopeExecution
     */
    @Override
    public void complete(ActivityExecution scopeExecution) {
        int loopCounter = getLoopVariable(scopeExecution, LOOP_COUNTER) + 1;
        int nrOfInstances = getLoopVariable(scopeExecution, NUMBER_OF_INSTANCES);
        int nrOfCompletedInstances = getLoopVariable(scopeExecution, NUMBER_OF_COMPLETED_INSTANCES) + 1;
        setLoopVariable(scopeExecution, NUMBER_OF_COMPLETED_INSTANCES, nrOfCompletedInstances);

        if (loopCounter == nrOfInstances || completionConditionSatisfied(scopeExecution)) {
            leave(scopeExecution);
        } else {
            PvmActivity innerActivity = getInnerActivity(scopeExecution.getActivity());
            performInstance(scopeExecution, innerActivity, loopCounter);
        }
    }
}
